package visiopuce.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import visiopuce.ApplicationContexte;
import visiopuce.HibernateUtil;
import visiopuce.DAO.CotationDAOImpl;
import visiopuce.DAO.HistoriqueDAO;
import visiopuce.DAO.HistoriqueDAOImpl;
import visiopuce.DAO.PersonneDAO;
import visiopuce.DAO.PersonneDAOImpl;
import visiopuce.DAO.PersonnePhenotypeDAO;
import visiopuce.DAO.PersonnePhenotypeDAOImpl;
import visiopuce.DAO.PhenotypeDAO;
import visiopuce.DAO.PhenotypeDAOImpl;
import visiopuce.objets.Alteration;
import visiopuce.objets.Analyse;
import visiopuce.objets.Cotation;
import visiopuce.objets.Historique;
import visiopuce.objets.Personne;
import visiopuce.objets.PersonnePhenotype;
import visiopuce.objets.Phenotype;
import visiopuce.objets.Prelevement;
import visiopuce.objets.Puce;
import visiopuce.objets.Recherche;
import visiopuce.objets.Resultat;

public class PersonneServiceImpl implements PersonneService {

	private static final Log log = LogFactory.getLog(PersonneService.class);

	private PersonneDAO personneDAO = PersonneDAOImpl.getInstance();
	private PhenotypeDAO phenotypeDAO = PhenotypeDAOImpl.getInstance();
	private PersonnePhenotypeDAO personnePhenotypeDAO = PersonnePhenotypeDAOImpl.getInstance();
	private HistoriqueDAO historiqueDAO = HistoriqueDAOImpl.getInstance();

	private Object personne;

	/** Constructeur priv� */
	private PersonneServiceImpl() {
	}

	/** Instance unique non pr�initialis�e */
	private static PersonneServiceImpl INSTANCE = null;

	/** Point d'acc�s pour l'instance unique du singleton */
	public static PersonneService getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new PersonneServiceImpl();
		}
		return INSTANCE;
	}

	public List<Personne> findAllByRecherche(Recherche recherche) {
		List<Personne> personnes = null;

		HibernateUtil.beginTransaction();
		personnes = personneDAO.findAllByRecherche(recherche);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return personnes;
	}

	public Personne getPersonneById(int idPersonne) {
		Personne personne = null;
		if (idPersonne != 0) {
			boolean aCommit = false;
			if (!HibernateUtil.getSession().getTransaction().isActive()) {
				HibernateUtil.beginTransaction();
				aCommit = true;
			}
			personne = personneDAO.findByID(Personne.class, idPersonne);
			if (aCommit) {
				HibernateUtil.commitTransaction();
				HibernateUtil.closeSession();
			}
		} else {
			personne = new Personne();
			personne.setIdPersonne(0);
			// personne.setGroupe(ApplicationContexte.getInstance().getUtilisateur().getGroupe());
		}

		return personne;
	}

	public String[] getNomFromString(String debut) {
		String[] noms = null;
		HibernateUtil.beginTransaction();
		noms = (String[]) personneDAO.getNomFromString(debut);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return noms;
	}

	public String[] getNomPrenomFromString(String debut) {
		String[] noms = null;
		HibernateUtil.beginTransaction();
		noms = (String[]) personneDAO.getNomPrenomFromString(debut);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return noms;
	}

	public String[] getPrenomFromNomPrenom(String nom, String prenom) {
		String[] prenoms = null;
		HibernateUtil.beginTransaction();
		prenoms = (String[]) personneDAO.getNomFromNomPrenom(nom, prenom);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return prenoms;
	}

	public Personne getPersonneByNomPrenomDateNaissance(String nom, String prenom, Date dateNaissance) {
		Personne personne = null;
		HibernateUtil.beginTransaction();
		personne = personneDAO.getPersonneByNomPrenomDateNaissance(nom, prenom, dateNaissance);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return personne;
	}

	public void save(Personne personne) {
		HibernateUtil.beginTransaction();
		try {
			ArrayList<Cotation> listeC = new ArrayList<Cotation>();
			personneDAO.save(personne);
			Historique h = new Historique();
			h.setDate(new Date());
			h.setRequete("Enregistrement " + personne.toString());
			h.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h);
			personnePhenotypeDAO.deleteAllByidPersonne(personne.getIdPersonne());
			ArrayList<PersonnePhenotype> phenos = personne.getPersonnePhenotypes();
			if (phenos != null) {
				for (PersonnePhenotype personnePhenotype : phenos) {
					personnePhenotypeDAO.save(personnePhenotype);
					Historique h2 = new Historique();
					h2.setDate(new Date());
					h2.setRequete("Enregistrement " + personnePhenotype.toString());
					h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
					historiqueDAO.save(h2);
				}
			}
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	public ArrayList<Phenotype> getPhenotypesByIdPersonne(Integer idPersonne) {
		ArrayList<Phenotype> phenotypes = null;

		HibernateUtil.beginTransaction();
		phenotypes = phenotypeDAO.getPhenotypesByIdPersonne(idPersonne);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return phenotypes;
	}

	public Personne ippUnique(String numIPP, Integer idPersonne) {
		Personne p = null;
		HibernateUtil.beginTransaction();
		p = personneDAO.ippUnique(numIPP, idPersonne);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return p;
	}

	public ArrayList<Personne> nomUnique(String nom, Integer idPersonne) {
		ArrayList<Personne> personnes = null;
		HibernateUtil.beginTransaction();
		personnes = personneDAO.nomUnique(nom, idPersonne);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return personnes;
	}

	public ArrayList<Personne> nomPrenomUnique(String nom, String prenom) {
		ArrayList<Personne> personnes = null;
		HibernateUtil.beginTransaction();
		personnes = personneDAO.nomPrenomUnique(nom, prenom);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return personnes;
	}

	public Personne refresh(Personne personne) {
		if (personne.getIdPersonne() != 0) {
			HibernateUtil.beginTransaction();
			HibernateUtil.getSession().refresh(personne);
			HibernateUtil.closeSession();
		}
		return personne;
	}

	@Override
	public int getIdPersonneFromObject(Object obj) {
		int id = 0;
		boolean commit = false;
		if (HibernateUtil.getSession().getTransaction() == null || (HibernateUtil.getSession().getTransaction() != null && !HibernateUtil.getSession().getTransaction().isActive())) {
			HibernateUtil.beginTransaction();
			commit = true;
		}
		if (obj instanceof Puce) {

			id = personneDAO.getIdPersonneFromPuce(((Puce) obj).getIdPuce());

		}
		if (obj instanceof Prelevement) {

			id = personneDAO.getIdPersonneFromPrelevement(((Prelevement) obj).getIdPrelevement());

		}
		if (obj instanceof Analyse) {

			id = personneDAO.getIdPersonneFromAnalyse(((Analyse) obj).getIdAnalyse());

		}
		if (obj instanceof Resultat) {

			id = personneDAO.getIdPersonneFromResultat(((Resultat) obj).getIdResultat());

		}
		if (obj instanceof Alteration) {

			id = personneDAO.getIdPersonneFromAlteration(((Alteration) obj).getIdAlteration());

		}
		if (obj instanceof Puce) {

			id = personneDAO.getIdPersonneFromPuce(((Puce) obj).getIdPuce());

		}
		if (commit) {
			HibernateUtil.commitTransaction();
			HibernateUtil.closeSession();
		}

		return id;
	}

	@Override
	public String[] getPeronneAPasserPuceFromString(String debut) {
		SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
		HibernateUtil.beginTransaction();
		List<Object[]> objects = personneDAO.getPeronneAPasserPuceFromString(debut);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		String[] noms = new String[objects.size()];
		int i = 0;

		for (Object[] object : objects) {
			noms[i] = "";
			if (object[4] != null) {
				boolean urgent = (boolean) object[4];
				if (urgent) {
					noms[i] = "URGENT-";
				}
			}

			noms[i] += object[0] + " " + object[1] + " " + object[2] + " (" + object[5] + ") - n°" + object[3];
			i++;
		}
		return noms;
	}

	@Override
	public String getPeronneAPasserPuceFromIdPuce(int idPuce) {
		SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
		HibernateUtil.beginTransaction();
		Object[] object = personneDAO.getPeronneAPasserPuceFromIdPuce(idPuce);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		String noms = new String();
		int i = 0;

		noms = "";
		if (object[4] != null) {
			boolean urgent = (boolean) object[4];
			if (urgent) {
				noms = "URGENT-";
			}
		}

		noms += object[0] + " " + object[1] + " " + object[2] + " (" + object[5] + ") - n°" + object[3];

		return noms;
	}

	@Override
	public void delete(Personne personne) {
		try {
			HibernateUtil.beginTransaction();
			List<Cotation> cotations = CotationDAOImpl.getInstance().getCotationByidPersonne(personne.getIdPersonne());
			for (Cotation cotation : cotations) {
				Historique h2 = new Historique();
				h2.setDate(new Date());
				h2.setRequete("Suppression " + cotation.toString());
				h2.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
				historiqueDAO.save(h2);
				CotationDAOImpl.getInstance().delete(cotation);
			}
			personnePhenotypeDAO.deleteAllByidPersonne(personne.getIdPersonne());

			Historique h3 = new Historique();
			h3.setDate(new Date());
			h3.setRequete("Suppression " + personne.toString());
			h3.setUtilisateur(ApplicationContexte.getInstance().getUtilisateur());
			historiqueDAO.save(h3);

			personneDAO.delete(personne);
			HibernateUtil.commitTransaction();
		} catch (Exception ex) {
			ex.printStackTrace();
			HibernateUtil.rollbackTransaction();
		} finally {
			HibernateUtil.closeSession();
		}
	}

	@Override
	public Personne getPersonneByIpp(String ipp) {
		Personne personne = null;
		HibernateUtil.beginTransaction();
		personne = personneDAO.getPersonneByIpp(ipp);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return personne;
	}

	@Override
	public String getNomPrenomFromIdAnalyse(Integer idAnalyse) {
		String nomPrenom = "";
		HibernateUtil.beginTransaction();
		nomPrenom = personneDAO.getNomPrenomFromIdAnalyse(idAnalyse);
		HibernateUtil.commitTransaction();
		HibernateUtil.closeSession();
		return nomPrenom;
	}

}